package com.facebook.android;

import java.io.File;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Stack;

import com.appengine.utils.SavingAndLoadingCenter;
import com.sporteamws.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.widget.ImageView;

public class FBimageManager {
	private HashMap<String, SoftReference<Bitmap>> imageMap = new HashMap<String, SoftReference<Bitmap>>();

	private ImageQueue imageQueue = new ImageQueue();
//	private Thread imageLoaderThread = new Thread(new ImageQueueManager());
	private Context c = null;
	Handler setPic = null;

	public FBimageManager(Context context) {

//		imageLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);
		this.c = context;
		setPic = new Handler();

	}

	public void displayImage(String url, Activity activity, ImageView imageView) {
		if (imageMap.containsKey(url))
			imageView.setImageBitmap(imageMap.get(url).get());
		else {
			queueImage(url, activity, imageView);
			imageView.setImageResource(R.drawable.profile);
		}
	}

	private void queueImage(String url, Activity activity, ImageView imageView) {
		// This ImageView might have been used for other images, so we clear
		// the queue of old tasks before starting.
		imageQueue.Clean(imageView);
		ImageRef p = new ImageRef(url, imageView);

		synchronized (imageQueue.imageRefs) {
			imageQueue.imageRefs.push(p);
			imageQueue.imageRefs.notifyAll();
		}

		// Start thread if it's not started yet
	//	if (imageLoaderThread.getState() == Thread.State.NEW)
	//		imageLoaderThread.start();
		Thread imageLoaderThread = new Thread(new ImageQueueManager());
		imageLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);
		imageLoaderThread.start();
	}

	private Bitmap getBitmap(String fbID) {

		// Is the bitmap in our cache?
		Bitmap bitmap = SavingAndLoadingCenter.loadFriendImage(fbID, c);
		if (bitmap != null)
			return bitmap;

		// Nope, have to download it
		try {
			bitmap = FacebookUtils.GetProfilePic(fbID, "square");
			// save bitmap to cache for later
			SavingAndLoadingCenter.saveFriendImage(fbID, bitmap, c);

			return bitmap;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}
	}

	/** Classes **/

	private class ImageRef {
		public String fbID;
		public ImageView imageView;

		public ImageRef(String fbID, ImageView i) {
			this.fbID = fbID;
			imageView = i;
		}
	}

	// stores list of images to download
	private class ImageQueue {
		private Stack<ImageRef> imageRefs = new Stack<ImageRef>();

		// removes all instances of this ImageView
		public void Clean(ImageView view) {

			for (int i = 0; i < imageRefs.size();) {
				if (imageRefs.get(i).imageView == view)
					imageRefs.remove(i);
				else
					++i;
			}
		}
	}

	private class ImageQueueManager implements Runnable {
		@Override
		public void run() {
			try {
			//	while (true) {
					// Thread waits until there are images in the
					// queue to be retrieved
					if (imageQueue.imageRefs.size() == 0) {
						synchronized (imageQueue.imageRefs) {
							imageQueue.imageRefs.wait();
						}
					}

					// When we have images to be loaded
					if (imageQueue.imageRefs.size() != 0) {
						ImageRef imageToLoad;

						synchronized (imageQueue.imageRefs) {
							imageToLoad = imageQueue.imageRefs.pop();
						}

						Bitmap bmp = getBitmap(imageToLoad.fbID);
						imageMap.put(imageToLoad.fbID,
								new SoftReference<Bitmap>(bmp));
						Object tag = imageToLoad.imageView.getTag();

						// Make sure we have the right view - thread safety
						// defender
						if (tag != null
								&& ((String) tag).equals(imageToLoad.fbID)) {
							BitmapDisplayer bmpDisplayer = new BitmapDisplayer(
									bmp, imageToLoad.imageView);
							setPic.post(bmpDisplayer);
						}
					}

		//			if (Thread.interrupted())
		//				break;
		//		}
			} catch (InterruptedException e) {
			}
		}
	}

	// Used to display bitmap in the UI thread
	private class BitmapDisplayer implements Runnable {
		Bitmap bitmap;
		ImageView imageView;

		public BitmapDisplayer(Bitmap b, ImageView i) {
			bitmap = b;
			imageView = i;
		}

		public void run() {
			if (bitmap != null)
				imageView.setImageBitmap(bitmap);
			else
				imageView.setImageResource(R.drawable.profile);
		}
	}
}
